import base

class ULA(object):
    def __init__(self):
        self.operando1 = base.TAM*'0'
        self.operando2 = base.TAM*'0'
        self.zeraFlags()
        self.zeraResultado()
        
    def zeraFlags(self):
        self.carry = '0'
        self.overflow = '0'
        self.sinal = '0'
        self.zero = '0'
    
    def zeraResultado(self):
        self.resultado = ''
        
    def setOperandos(self,a,b):
        self.operando1 = a
        self.operando2 = b
    
    def soma(self):
        self.zeraResultado()
        self.carry='0'       
        for i in range(base.TAM-1,-1,-1):
            if (self.carry == '1'):
                if ((self.operando1[i] == '1') and (self.operando2[i] == '1')):
                    self.carry = '1'
                    self.resultado = self.resultado+'1'
                if ((self.operando1[i] == '0') and (self.operando2[i] == '1')):
                    self.carry = '1'
                    self.resultado = self.resultado+'0'
                if ((self.operando1[i] == '1') and (self.operando2[i] == '0')):
                    self.carry = '1'
                    self.resultado = self.resultado+'0'
                if ((self.operando1[i] == '0') and (self.operando2[i] == '0')):
                    self.carry = '0'
                    self.resultado = self.resultado+'1'
            else:
                if ((self.operando1[i] == '1') and (self.operando2[i] == '1')):
                    self.carry = '1'
                    self.resultado = self.resultado+'0'
                if ((self.operando1[i] == '0') and (self.operando2[i] == '1')):
                    self.carry = '0'
                    self.resultado = self.resultado+'1'
                if ((self.operando1[i] == '1') and (self.operando2[i] == '0')):
                    self.carry = '0'
                    self.resultado = self.resultado+'1'
                if ((self.operando1[i] == '0') and (self.operando2[i] == '0')):
                    self.carry = '0'
                    self.resultado = self.resultado+'0'
        self.resultado=self.resultado[::-1]
        
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        self.overflow='0'
        if(self.operando1[0]=='1' and self.operando2[0]=='1'):
            if self.resultado[0]=='0':
                self.overflow='1'
        if(self.operando1[0]=='0' and self.operando2[0]=='0'):
            if self.resultado[0]=='1':
                self.overflow='1'
        
        return self.resultado
    
    def notOperando1(self):
        self.zeraResultado()        
        for i in range(base.TAM-1,-1,-1):
            if (self.operando1[i] == '0'):
                self.resultado = self.resultado+'1'
            else:
                self.resultado = self.resultado+'0'
        self.resultado=self.resultado[::-1]
       
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        
        return self.resultado
    
    def notOperando2(self):
        self.zeraResultado()        
        for i in range(base.TAM-1,-1,-1):
            if (self.operando2[i] == '0'):
                self.resultado = self.resultado+'1'
            else:
                self.resultado = self.resultado+'0'
        self.resultado=self.resultado[::-1]
        
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        
        return self.resultado
    
    def complementoA2Operando1(self):
        self.zeraResultado()
        self.notOperando1()
        self.setOperandos(self.resultado,(base.TAM-1)*'0'+'1')
        self.soma()
        
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        
        return self.resultado
    
    def complementoA2Operando2(self):
        self.zeraResultado()
        self.notOperando2()
        self.setOperandos((base.TAM-1)*'0'+'1',self.resultado)
        self.soma()
        
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        
        return self.resultado
    def andLogico(self):
        self.zeraResultado()
        for i in range(0,base.TAM):
            if ((self.operando1[i] == '1') and (self.operando2[i] == '1')):
                self.resultado = self.resultado + '1'
            else:
                self.resultado = self.resultado + '0'
        
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        
        return self.resultado
    def orLogico(self):
        self.zeraResultado()
        for i in range(0,base.TAM):
            if ((self.operando1[i] == '1') or (self.operando2[i] == '1')):
                self.resultado = self.resultado + '1'
            else:
                self.resultado = self.resultado + '0'
                
        
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        
        return self.resultado
    def copiaEntradaOperando1(self):
        self.zeraResultado()
        for i in range(0,base.TAM):
            self.resultado=self.resultado+self.operando1[i]
        
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        
        return self.resultado
    
    def copiaEntradaOperando2(self):
        self.zeraResultado()
        for i in range(0,base.TAM):
            self.resultado=self.resultado+self.operando2[i]
        
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        
        return self.resultado
    
    def clearOperando(self):
        self.zeraResultado()
        self.resultado='0'*base.TAM
        
        #setando flags
        self.zero=0
        
        return self.resultado
        
    def shiftLeft(self):
        self.zeraResultado()
        self.carry = self.operando1[base.TAM-1] #setando carry
        for i in range(base.TAM-2,-1,-1):
            self.resultado = self.resultado+self.operando1[i]
        self.resultado = self.resultado+'0'
        
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        
        return self.resultado
        
    def shiftRight(self):
        self.zeraResultado()
        self.carry = self.operando1[0] #setando carry
        for i in range(1,base.TAM):
            self.resultado = self.resultado+self.operando1[i]
        self.resultado = self.resultado+'0'
        self.resultado=self.resultado[::-1]
        
        #setando flags
        if(self.resultado==base.TAM*'0'):
            self.zero='1'
        else:
            self.zero='0'
        if(self.resultado[0]=='1'):
            self.sinal='1'
        else:
            self.sinal='0'
        
        return self.resultado
    